package com.imut.lagain.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.imut.lagain.entity.*;
import com.imut.lagain.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 心情小偷游戏服务实现类
 */
@Service
public class MoodThiefGameServiceImpl implements IMoodThiefGameService {
    private static final Logger log = LoggerFactory.getLogger(MoodThiefGameServiceImpl.class);

    
    private final IMoodThiefService moodThiefService;
    private final IMoodStealRecordService moodStealRecordService;
    private final IMemoryEntryService memoryEntryService;
    private final IHumorMessageService humorMessageService;
    private final IUserService userService;
    private final IMemoryCapsuleService memoryCapsuleService;
    
    public MoodThiefGameServiceImpl(IMoodThiefService moodThiefService,
                                   IMoodStealRecordService moodStealRecordService,
                                   IMemoryEntryService memoryEntryService,
                                   IHumorMessageService humorMessageService,
                                   IUserService userService,
                                   IMemoryCapsuleService memoryCapsuleService) {
        this.moodThiefService = moodThiefService;
        this.moodStealRecordService = moodStealRecordService;
        this.memoryEntryService = memoryEntryService;
        this.humorMessageService = humorMessageService;
        this.userService = userService;
        this.memoryCapsuleService = memoryCapsuleService;
    }
    private static final int STEAL_COOLDOWN_HOURS = 6;
    private static final int MAX_DAILY_STEALS = 3;
    private static final int RECOVERY_TIME_LIMIT_HOURS = 24;
    
    /**
     * 执行偷取操作
     */
    @Override
    @Transactional
    public Map<String, Object> performSteal(Long thiefUserId, Long victimUserId, Long thiefId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            if (!canSteal(thiefUserId, victimUserId)) {
                result.put("success", false);
                result.put("message", "今日偷取次数已达上限或冷却时间未到");
                return result;
            }
            MoodThief thief = moodThiefService.getById(thiefId);
            if (thief == null) {
                result.put("success", false);
                result.put("message", "心情小偷不存在");
                return result;
            }
            List<MemoryEntry> stealableEntries = getStealableEntries(victimUserId, thiefUserId);
            if (stealableEntries.isEmpty()) {
                result.put("success", false);
                result.put("message", "没有可偷取的心情条目");
                return result;
            }
            Random random = new Random();
            MemoryEntry targetEntry = stealableEntries.get(random.nextInt(stealableEntries.size()));
            float successRate = calculateStealSuccessRate(thief, thiefUserId, victimUserId);
            boolean stealSuccess = random.nextFloat() < successRate;
            MoodStealRecord stealRecord = new MoodStealRecord();
            stealRecord.setThiefId(thiefId);
            stealRecord.setThiefUserId(thiefUserId);
            stealRecord.setVictimUserId(victimUserId);
            stealRecord.setEntryId(targetEntry.getId());
            stealRecord.setStealTime(LocalDateTime.now());
            stealRecord.setRecoveryAttempted(false);
            stealRecord.setEntryKept(!stealSuccess);
            stealRecord.setCreateTime(LocalDateTime.now());
            
            moodStealRecordService.save(stealRecord);
            String moodType = stealSuccess ? "bad" : "good";
            String humorMessage = getHumorMessage(moodType, thief.getThiefType());
            
            result.put("success", true);
            result.put("stealSuccess", stealSuccess);
            result.put("message", humorMessage);
            result.put("thief", thief);
            result.put("targetEntry", targetEntry);
            result.put("stealRecord", stealRecord);
            
            log.info("用户{}使用{}偷取用户{}的心情条目{}，结果：{}", 
                    thiefUserId, thief.getDisplayName(), victimUserId, targetEntry.getId(), stealSuccess ? "成功" : "失败");
            
        } catch (Exception e) {
            log.error("执行偷取操作失败", e);
            result.put("success", false);
            result.put("message", "偷取操作失败：" + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 尝试追回被偷的心情
     */
    @Override
    @Transactional
    public Map<String, Object> attemptRecovery(Long stealRecordId, Long victimUserId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            MoodStealRecord stealRecord = moodStealRecordService.getById(stealRecordId);
            if (stealRecord == null) {
                result.put("success", false);
                result.put("message", "偷取记录不存在");
                return result;
            }
            if (!stealRecord.getVictimUserId().equals(victimUserId)) {
                result.put("success", false);
                result.put("message", "无权限进行此操作");
                return result;
            }
            if (stealRecord.getRecoveryAttempted()) {
                result.put("success", false);
                result.put("message", "已经尝试过追回，不能重复操作");
                return result;
            }
            LocalDateTime stealTime = stealRecord.getStealTime();
            if (stealTime.plusHours(RECOVERY_TIME_LIMIT_HOURS).isBefore(LocalDateTime.now())) {
                result.put("success", false);
                result.put("message", "追回时间已过，无法追回");
                return result;
            }
            float recoveryRate = calculateRecoverySuccessRate(stealRecord);
            Random random = new Random();
            boolean recoverySuccess = random.nextFloat() < recoveryRate;
            stealRecord.setRecoveryAttempted(true);
            stealRecord.setRecoverySuccess(recoverySuccess);
            if (recoverySuccess) {
                stealRecord.setEntryKept(true);
            }
            moodStealRecordService.updateById(stealRecord);
            MoodThief thief = moodThiefService.getById(stealRecord.getThiefId());
            String moodType = recoverySuccess ? "good" : "bad";
            String humorMessage = getHumorMessage(moodType, thief != null ? thief.getThiefType() : "default");
            
            result.put("success", true);
            result.put("recoverySuccess", recoverySuccess);
            result.put("message", humorMessage);
            result.put("stealRecord", stealRecord);
        } catch (Exception e) {
            log.error("尝试追回失败", e);
            result.put("success", false);
            result.put("message", "追回操作失败：" + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 获取可偷取的记忆条目
     */
    @Override
    public List<MemoryEntry> getStealableEntries(Long victimUserId, Long thiefUserId) {
        try {
            List<MemoryEntry> allEntries = memoryEntryService.getEntriesByUserId(victimUserId);
            List<Long> stolenEntryIds = moodStealRecordService.list().stream()
                    .filter(record -> record.getVictimUserId().equals(victimUserId))
                    .filter(record -> !record.getEntryKept())
                    .map(MoodStealRecord::getEntryId)
                    .collect(Collectors.toList());
            
            return allEntries.stream()
                    .filter(entry -> !stolenEntryIds.contains(entry.getId()))
                    .filter(entry -> entry.getContent() != null && !entry.getContent().trim().isEmpty())
                    .collect(Collectors.toList());
            
        } catch (Exception e) {
            log.error("获取可偷取条目失败", e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 获取随机心情小偷
     */
    @Override
    public MoodThief getRandomThief() {
        try {
            List<MoodThief> activeThieves = moodThiefService.findAllActive();
            if (activeThieves.isEmpty()) {
                return null;
            }
            
            Random random = new Random();
            return activeThieves.get(random.nextInt(activeThieves.size()));
        } catch (Exception e) {
            log.error("获取随机心情小偷失败", e);
            return null;
        }
    }
    
    /**
     * 获取幽默文案
     */
    @Override
    public String getHumorMessage(String moodType, String thiefType) {
        try {
            List<HumorMessage> messages = humorMessageService.findByMoodTypeAndThiefType(moodType, thiefType);
            if (messages.isEmpty()) {
                return getDefaultHumorMessage(moodType);
            }
            
            Random random = new Random();
            HumorMessage selectedMessage = messages.get(random.nextInt(messages.size()));
            return selectedMessage.getMessage();
        } catch (Exception e) {
            log.error("获取幽默文案失败", e);
            return getDefaultHumorMessage(moodType);
        }
    }
    
    /**
     * 检查用户是否可以进行偷取操作
     */
    @Override
    public boolean canSteal(Long thiefUserId, Long victimUserId) {
        try {
            if (thiefUserId.equals(victimUserId)) {
                return false;
            }
            
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime todayStart = now.toLocalDate().atStartOfDay();
            long todayStealCount = moodStealRecordService.list().stream()
                    .filter(record -> record.getThiefUserId().equals(thiefUserId))
                    .filter(record -> record.getStealTime().isAfter(todayStart))
                    .count();
            
            if (todayStealCount >= MAX_DAILY_STEALS) {
                return false;
            }
            Optional<MoodStealRecord> lastSteal = moodStealRecordService.list().stream()
                    .filter(record -> record.getThiefUserId().equals(thiefUserId))
                    .max(Comparator.comparing(MoodStealRecord::getStealTime));
            
            if (lastSteal.isPresent()) {
                LocalDateTime lastStealTime = lastSteal.get().getStealTime();
                if (lastStealTime.plusHours(STEAL_COOLDOWN_HOURS).isAfter(now)) {
                    return false;
                }
            }
            
            return true;
        } catch (Exception e) {
            log.error("检查偷取权限失败", e);
            return false;
        }
    }
    
    /**
     * 获取用户的偷取记录
     */
    @Override
    public List<MoodStealRecord> getUserStealRecords(Long userId, boolean isThief) {
        try {
            return moodStealRecordService.list().stream()
                    .filter(record -> isThief ? 
                            record.getThiefUserId().equals(userId) : 
                            record.getVictimUserId().equals(userId))
                    .sorted(Comparator.comparing(MoodStealRecord::getStealTime).reversed())
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取用户偷取记录失败", e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 计算偷取成功率
     */
    @Override
    public float calculateStealSuccessRate(MoodThief thief, Long thiefUserId, Long victimUserId) {
        float baseRate = thief.getSuccessRate();
        return Math.max(0.1f, Math.min(0.9f, baseRate));
    }
    
    /**
     * 计算追回成功率
     */
    @Override
    public float calculateRecoverySuccessRate(MoodStealRecord stealRecord) {
        try {
            MoodThief thief = moodThiefService.getById(stealRecord.getThiefId());
            if (thief == null) {
                return 0.5f;
            }
            float baseRecoveryRate = 1.0f - thief.getEscapeRate();
            LocalDateTime stealTime = stealRecord.getStealTime();
            long hoursElapsed = java.time.Duration.between(stealTime, LocalDateTime.now()).toHours();
            float timeDecay = Math.max(0.1f, 1.0f - (hoursElapsed / (float) RECOVERY_TIME_LIMIT_HOURS) * 0.5f);
            
            return Math.max(0.1f, Math.min(0.9f, baseRecoveryRate * timeDecay));
        } catch (Exception e) {
            log.error("计算追回成功率失败", e);
            return 0.5f;
        }
    }
    
    /**
     * 获取偷取统计信息
     */
    @Override
    public Map<String, Object> getStealStatistics(Long userId) {
        Map<String, Object> stats = new HashMap<>();
        
        try {
            List<MoodStealRecord> asThief = getUserStealRecords(userId, true);
            List<MoodStealRecord> asVictim = getUserStealRecords(userId, false);
            long totalSteals = asThief.size();
            long successfulSteals = asThief.stream()
                    .filter(record -> !record.getEntryKept())
                    .count();
            long totalStolen = asVictim.size();
            long successfulRecoveries = asVictim.stream()
                    .filter(record -> record.getRecoveryAttempted() && record.getRecoverySuccess())
                    .count();
            
            stats.put("totalSteals", totalSteals);
            stats.put("successfulSteals", successfulSteals);
            stats.put("stealSuccessRate", totalSteals > 0 ? (float) successfulSteals / totalSteals : 0.0f);
            stats.put("totalStolen", totalStolen);
            stats.put("successfulRecoveries", successfulRecoveries);
            stats.put("recoverySuccessRate", totalStolen > 0 ? (float) successfulRecoveries / totalStolen : 0.0f);
            LocalDateTime todayStart = LocalDateTime.now().toLocalDate().atStartOfDay();
            long todayStealCount = asThief.stream()
                    .filter(record -> record.getStealTime().isAfter(todayStart))
                    .count();
            stats.put("remainingDailySeals", Math.max(0, MAX_DAILY_STEALS - todayStealCount));
            
        } catch (Exception e) {
            log.error("获取偷取统计信息失败", e);
        }
        
        return stats;
    }
    
    /**
     * 获取默认幽默文案
     */
    private String getDefaultHumorMessage(String moodType) {
        if ("bad".equals(moodType)) {
            return "哎呀！你的好心情被小偷偷走了，不过别担心，坏心情也有它的价值呢~";
        } else {
            return "哈哈！小偷这次失手了，你的好心情安然无恙！";
        }
    }
}

